package edu.upenn.cis.cis550.hw3.client;

import java.util.Iterator;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.xml.client.Node;

import edu.upenn.cis.cis550.hw3.shared.Relation;
import edu.upenn.cis.cis550.hw3.shared.Tuple;

/**
 * This is the main class for generating Web table results for CIS 550 HW1
 * 
 * @author zives
 * 
 */
public class testHomepage implements EntryPoint {

    int userid = 10;

    Grid topPhotos = new Grid(2, 5);

    VerticalPanel recommendations = new VerticalPanel();

    VerticalPanel searchPanel = new VerticalPanel();

    PopupPanel popup = new PopupPanel();

    VerticalPanel popupContents = new VerticalPanel();

    private final QueryTablesAsync queryService = GWT.create(QueryTables.class);

    private JavaScriptObject theGraph;

    /**
     * This is the entry point method.
     */

    public void onModuleLoad() {

        PopupPanel friendNetwork = new PopupPanel();
        popup.hide();
        popup.add(popupContents);

        // PopupPanel friendRecommendations = new PopupPanel();
        searchPanel.addStyleName("eastWidget");

        recommendations.addStyleName("westWidget");

        // ScrollPanel topPhotosScrollable = new ScrollPanel(topPhotos);
        VerticalPanel topPhotosScrollable = new VerticalPanel();
        topPhotosScrollable.add(topPhotos);
        topPhotosScrollable.addStyleName("northWidget");

        friendNetwork.addStyleDependentName("southWidget");
        ScrollPanel friendNetworkScrollable = new ScrollPanel(friendNetwork);

        // Assemble Main panel.

        DockLayoutPanel appPanel = new DockLayoutPanel(Unit.PCT);

        appPanel.addWest(recommendations, 20);

        appPanel.addEast(searchPanel, 20);

        appPanel.addSouth(friendNetworkScrollable, 50);

        appPanel.addNorth(topPhotosScrollable, 50);

        HTML infoVis = new HTML("<div id=\"infoVis\"></div>");
        infoVis.addStyleName("infoVis");

        friendNetwork.add(infoVis);

        RootLayoutPanel.get().add(appPanel);

        getFirstPerson();
        refreshTopPhotoPanel();
        refreshRecommendationPanel();
        refreshSearchPanel();

    }

    private void refreshSearchPanel() {
        VerticalPanel search = new VerticalPanel();
        final VerticalPanel results = new VerticalPanel();
        search.add(new HTML("Hello"));
        final TextBox searchBox = new TextBox();
        Button searchButton = new Button();
        searchButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                String keywords = searchBox.getText();

                AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {
                    public void onFailure(Throwable caught) {

                    }

                    public void onSuccess(Relation r) {
                        if (r.isEmpty()) {
                            System.out.println("no results");
                            return;
                        }
                        Iterator<Tuple> i = r.iterator();
                        while (i.hasNext()) {
                            Tuple t = i.next();
                            Image im = new Image();
                            im.setUrl(t.getValue("url").toString());
                            results.add(im);
                        }
                    }
                };

                queryService.getSearchedPhotos(keywords,
                        Integer.toString(userid), callback);

            }
        });

        search.add(searchBox);
        search.add(searchButton);

        results.add(new HTML("world."));

        searchPanel.add(search);
        searchPanel.add(results);

    }

    private void refreshRecommendationPanel() {
        
    }

    private void refreshTopPhotoPanel() {
        getTopPhotos();
    }

    private void getTopPhotos() {
        topPhotos.setWidth("50px");
        topPhotos.addStyleName("topPhotosGrid");
        // topPhotos.getColumnFormatter().setWidth(0, "20px");
        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {
            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {
                Iterator<Tuple> i = r.iterator();

                // System.out.println(i.next().getValue("finalScore"));

                for (int row = 0; row < topPhotos.getRowCount(); row++)
                    for (int col = 0; col < topPhotos.getColumnCount(); col++) {
                        if (i.hasNext()) {
                            Tuple t = i.next();
                            VerticalPanel p = new VerticalPanel();
                            Image im = new Image();
                            String url = t.getValue("url").toString();
                            im.setUrl(url);
                            // String html = "<img src=\"" +
                            // t.getValue("url").toString() + "\"/>";
                            // System.out.println(html);
                            p.add(im);
                            p.setTitle(t.getValue("finalScore").toString());
                            topPhotos.setWidget(row, col, p);
                            System.out.println("Putting " + im.getUrl()
                                    + " in row " + row + " and col " + col
                                    + " with score "
                                    + t.getValue("finalScore").toString());
                        }
                    }
            }
        };

        queryService.getTopScoringPhotos(Integer.toString(userid), callback);

    }

    public void drawNodeAndNeighbors(int person) {
        System.out.println("Requesting data for " + person);

        queryService.getFriendsVisualizerXML(person,
                new AsyncCallback<String>() {

                    public void onFailure(Throwable caught) {
                        // TODO Auto-generated method stub

                    }

                    public void onSuccess(String result) {
                        Node n = XMLandJSON.parseXML(result);

                        if (n != null) {
                            FriendVisualization.addToGraph(theGraph, XMLandJSON
                                    .getJsonForUser(n).toString());
                        }
                    }
                });

    }

    public void getFirstPerson() {
        AsyncCallback<String> callback = new AsyncCallback<String>() {

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub

            }

            public void onSuccess(String result) {

                try {
                    JSONObject x = XMLandJSON.getJsonForUser(XMLandJSON
                            .parseXML(result));
                    if (x != null) {
                        // System.out.println(x.toString());
                        theGraph = FriendVisualization.createGraph(
                                x.toString(), testHomepage.this);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        queryService.getFriendsVisualizerXML(userid, callback);
    }

    public void updateInfoPanel(int id) {
        popupContents.clear();
        getUserInfo(id);
        getStudentInfo(id);
        getProfInfo(id);
        /*Button close = new Button("Close");
        close.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                popup.hide();
            }
        });
        popupContents.add(close);
        */
        showInfoPanel();
    }
    
    public void showInfoPanel() {
        popup.center();
    }

    public void hideInfoPanel() {
        System.out.println("close");
        popup.hide();
    }

    private void getProfInfo(int id) {
        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub
            }

            public void onSuccess(Relation result) {
                if (result.isEmpty()) {
                    return;
                }
                Tuple t = result.iterator().next();
                StringBuffer info = new StringBuffer();

                info.append("<p>" + t.getValue("title") + "</p>");
                info.append("<p>Room Number: " + t.getValue("roomNumber")
                        + "</p>");
                info.append("<p>Research Area: " + t.getValue("researchArea")
                        + "</p>");
                info.append("<p>" + t.getValue("academicInstitution") + "</p>");

                System.out.println(info.toString());
                popupContents.add(new HTML(info.toString()));

            }
        };

        queryService.getProfessorInfo(Integer.toString(id), callback);

    }

    private void getStudentInfo(int id) {
        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub
            }

            public void onSuccess(Relation result) {
                if (result.isEmpty()) {
                    return;
                }

                Tuple t = result.iterator().next();
                System.out.println(t.getSchema().toString());
                System.out.println(t.toString());
                StringBuffer info = new StringBuffer();

                info.append("<p>Year: " + t.getValue("year") + "</p>");
                info.append("<p>Major: " + t.getValue("major") + "</p>");
                info.append("<p>GPA: " + t.getValue("GPA") + "</p>");
                info.append("<p>" + t.getValue("academicInstitution") + "</p>");

                System.out.println(info.toString());
                popupContents.add(new HTML(info.toString()));

            }
        };

        queryService.getStudentInfo(Integer.toString(id), callback);

    }

    public void getUserInfo(int id) {
        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub
            }

            public void onSuccess(Relation result) {
                Tuple t = result.iterator().next();
                StringBuffer info = new StringBuffer();

                info.append("<p>" + t.getValue("firstName") + " "
                        + t.getValue("lastName") + "</p>");
                info.append("<p>" + t.getValue("email") + "</p>");
                info.append("<p>" + t.getValue("dateBirth") + "</p>");
                info.append("<p>" + t.getValue("gender") + "</p>");

                System.out.println(info.toString());
                popupContents.add(new HTML(info.toString()));

            }
        };

        queryService.getUserInfo(Integer.toString(id), callback);
    }
}
